from fastapi import APIRouter, Depends, Header, HTTPException
from typing import Optional

c02 = APIRouter()


async def common_parameters(q: Optional[str] = None, page: int = 1, limit: int = 100):
    return {"q": q, "page": page, "limit": limit}


@c02.get("dependency01")
async def dependency01(commons: dict = Depends(common_parameters)):
    return commons


"""Class as Dependencies 类作为依赖项"""
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baze"}]


class CommonQueryParams:
    def __init__(self, q: Optional[str] = None, page: int = 1, limit: int = 100):
        self.q = q
        self.page = page
        self.limit = limit


@c02.get("/class_as_dependencies")
# async def class_as_dependencies(commons: CommonQueryParams = Depends(CommonQueryParams)):
# async def class_as_dependencies(commons: CommonQueryParams = Depends()):
async def class_as_dependencies(commons=Depends(CommonQueryParams)):
    response = {}
    if commons.q:
        response.update({"q": commons.q})
    items = fake_items_db[commons.page: commons.page + commons.limit]
    response.update({"items": items})
    return response


""""Sub-Dependencies 子依赖"""


def query(q: Optional[str] = None):
    return q


def sub_query(q: str = Depends(query), last_query: Optional[str] = None):
    if not q:
        return last_query
    return q


@c02.get("/sub_dependency")
async def sub_dependency(final_query: str = Depends(sub_query, use_cache=True)):
    return {"sub_dependency": final_query}


"""路径操作导入依赖"""


async def verify_token(x_token: str = Header(...)):
    """
    没有返回值的子依赖
    :param x_token:
    :return:
    """
    if x_token != "token":
        raise HTTPException(status_code=400, detail="X-Token header invalid")
    return x_token


async def verify_key(x_key: str = Header(...)):
    """
    有返回的子依赖， 但是返回值不会被调用
    :param x_key:
    :return:
    """
    if x_key != 'key':
        raise HTTPException(status_code=400, detail="X-Key header invalid")
    return x_key


"""全局依赖"""
c02 = APIRouter(dependencies=[Depends(verify_key), Depends(verify_token)])


@c02.get("/dependency_path", dependencies=[Depends(verify_key), Depends(verify_token)])
async def dependency_path():
    return [{"username": "user01"}, {"username": "user02"}]


"""带yield的依赖"""

# 共享数据库连接
async def get_db():
    db = "db_connection"
    try:
        yield db
    finally:
        db.endswith("db_close")

